/******************************************************************
 * 作者：sipeiliu
 * 邮箱：sipeiliu@163.com
 * 描述：光耦传感器，测量速度
 * 日期：2023.4.14
 ******************************************************************/

#include "/opt/sighter/inc/optocoupler.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>
#include <sys/time.h>

const float pi = 3.1415926;    // pi
const int wheel_diameter = 60; // 车轮直径，单位mm
const int disk_holes = 20;     // 编码盘孔洞数量
const int wpi = 8;             // 使用8号引脚接收传感器信号
int global_speed;              // 全局变量，车速，mm/s

/*中断处理函数, 计算实时速度*/
static void interrupt_rise(void)
{
    struct timeval tval;            // 当前时间
    long long int this_time;        // 本次时间点
    static long long int last_time; // 上次时间点
    static int count = 0;           // 计数

    if (count == 0)
    {
        gettimeofday(&tval, NULL); // 获取当前时间
        last_time = tval.tv_sec * 1000000 + tval.tv_usec;
        count++;
    }
    else if (count < disk_holes)
    {
        count++;
    }
    else if (count == disk_holes)
    {
        count = 0;                                        // 重新计数
        gettimeofday(&tval, NULL);                        // 获取当前时间
        this_time = tval.tv_sec * 1000000 + tval.tv_usec; // us
        // printf("%lld\n", this_time-last_time);
        global_speed = (pi * wheel_diameter * 1000000) / ((this_time - last_time)); // mm/s
        // printf("%d mm/s\n", global_speed);
        last_time = this_time;
    }
}
static void interrupt_fall(void)
{
    struct timeval tval;            // 当前时间
    long long int this_time;        // 本次时间点
    static long long int last_time; // 上次时间点
    static int count = 0;           // 计数

    if (count == 0)
    {
        gettimeofday(&tval, NULL); // 获取当前时间
        last_time = tval.tv_sec * 1000000 + tval.tv_usec;
        count++;
    }
    else if (count < disk_holes)
    {
        count++;
    }
    else if (count == disk_holes)
    {
        count = 0;                                        // 重新计数
        gettimeofday(&tval, NULL);                        // 获取当前时间
        this_time = tval.tv_sec * 1000000 + tval.tv_usec; // us
        // printf("%lld\n", (this_time-last_time));
        global_speed = (pi * wheel_diameter * 1000000) / ((this_time - last_time)); // mm/s
        printf("%d mm/s\n", global_speed);
        last_time = this_time;
    }
}

/*设置光耦传感器使用的引脚,初始化*/
static void optocoupler_gpio(void)
{
    wiringPiSetup();                                     // 初始化wiringpi
    pullUpDnControl(wpi, PUD_UP);                        // 设置引脚上拉输入
    wiringPiISR(wpi, INT_EDGE_RISING, &interrupt_rise);  // 设置中断上升沿触发
    wiringPiISR(wpi, INT_EDGE_FALLING, &interrupt_fall); // 设置中断下降沿触发
}

/*使能光耦传感器*/
void enable_optocoupler(void)
{
    optocoupler_gpio();
    while (1) // 主线程循环等待
    {
        sleep(1);
    }
}

// void main(void)
// {
//     enable_optocoupler();
// }
